import Blockutils from "@/utils/BlockUtils";
import { MotaInterface } from "@/mota";
import ScrollTool from "@/mota/tools/ScrollTool";
import { PropsInterface } from "@/mota/data/ItemDataUnit";
import PackUtils from "@/mota/utils/HeroUtils/PackUtils";
import { GetFloorList, MapFloor, MapInfo } from "@/mota/data/MapDataUtils";

export default class JumpFloorUtils extends ScrollTool<MapInfo> implements MotaInterface, PropsInterface {

    public pack!: PackUtils;

    public itemType!: PropsInterface["itemType"];

    public block: Blockutils = new Blockutils();

    public ZIndex: number = 4;

    public constructor() {
        super({
            Left: 11.5,
            Top: 3,
            Width: 3,
            Height: 7 + 0.5,
            Padding: 0.25,
            ItemWidth: 3 - 0.5 - 0.1,
            ItemHeight: 1.4,
            ItemPadding: 0.1,
            ScrollWidth: 0.1,
        });

    }

    public get isOpen() {
        return this.block.IsBlockUp;
    }

    public SetPack: PropsInterface["SetPack"] = async (pack, itemType) => {
        this.pack = pack;
        this.itemType = itemType;
    }

    public Use: PropsInterface["Use"] = async () => {
        const { pack: { hero: { Mota: { tip, map: { map, mapData } } } } } = this;

        const floor = map.floor;
        const list = <MapInfo[]>GetFloorList().reverse().map(floor => mapData.get(floor)).filter(info => info !== undefined);
        this.List.Value = list;
        this.SelectIndex = list.findIndex(info => info.floor === floor);

        await this.block.Wait(undefined, () => {
            this.SelectIndex = undefined;
        });
        return true;
    }

    public InView(): boolean {
        const { isOpen } = this;
        return isOpen;
    }

    public JudgeKey: MotaInterface["JudgeKey"] = (keyUtils): void => {
        if (!this.InView()) { return; }

        for (const key of keyUtils.keyHistory) {
            if (key === "Escape" || key === "f") {
                this.block.Release();
                keyUtils.delete(key);
            }
            else if (key === "ArrowUp") {
                this.SelectLast();
                if (this.SelectIndex === undefined) {
                    this.SelectIndex = 0;
                }
                keyUtils.delete(key);
            }
            else if (key === "ArrowDown") {
                this.SelectNext();
                if (this.SelectIndex === undefined) {
                    this.SelectIndex = this.List.Value.length - 1;
                }
                keyUtils.delete(key);
            }
            else if (key === "Enter" || key === " ") {
                if (this.SelectItem !== undefined) {
                    this.pack.hero.Mota.map.LoadMap(this.SelectItem.floor);
                }
                this.block.Release();
                keyUtils.delete(key);
            }
        }
    }

    public mousewheel: MotaInterface["mousewheel"] = (delta: number) => {
        if (!this.InView()) { return; }
        const isDown = delta > 0;
        if (this.SelectIndex !== undefined) {
            this.SelectIndex += isDown ? 1 : -1;
        }
    }

    public Draw: MotaInterface["Draw"] = (draw) => {
        if (!this.InView()) { return; }

        if (this.SelectItem === undefined) { return; }

        const { SelectItem, pack: { hero: { Mota: { map: { map } } } } } = this;
        const { size: { Value: Size } } = draw;

        const size = (Math.floor(Size * 0.6) / Size);

        const { _2d } = draw;
        _2d.save();

        _2d.save();

        _2d.fillStyle = "#000000AA";
        draw.fillRect(4, 0, 11, 11);

        draw.translate(8 * size, 5 * size);
        SelectItem.unit.forEach((unit) => draw.DrawUnti(unit, ([x, y, w, h]) => [x * size, y * size, w * size, h * size]));

        draw.SetLineWidth(1 / 16);
        _2d.strokeStyle = "#FFFFFF";
        draw.strokeRect(0, 0, 11 * size, 11 * size);

        _2d.restore();

        _2d.fillStyle = "#FFFFFF";
        _2d.textAlign = "center";
        _2d.textBaseline = "top";
        draw.SetFont(800, 1 / 2, "Mota");
        draw.fillText("楼层跳跃", 9.5, 0.4);
        draw.SetFont(800, 1 / 2.5, "Mota");
        draw.fillText("\"当权杖被举起，能量将被转送到所及之处\"", 9.5, 1.5);

        const transparencyList = [0.2, 0.5, 1, 0.5, 0.2];
        const selectIndex = <number>this.SelectIndex;
        const list = this.List.Value;
        let start = selectIndex - 2;
        let end = selectIndex + 3;
        let top = 0;
        if (selectIndex < 2) {
            start = 0;
            top += 2 - selectIndex;
        }
        const showList = list.slice(start, end);

        const width = this.ItemWidth.Value;
        const height = this.ItemHeight.Value;
        const x = this.Left.Value;
        const y = this.Top.Value + top * height;

        _2d.save();

        showList.forEach((floor, i) => {
            _2d.globalAlpha = transparencyList[i + top];
            _2d.fillStyle = "#FFFFFF";
            _2d.textAlign = "center";
            _2d.textBaseline = "top";
            draw.SetFont(800, 1 / 2, "Mota");
            draw.fillText(`${floor.name}`, x + width / 2, y + height * i);
        });

        _2d.restore();

        _2d.restore();
    }
}